package org.client.iot.ble;

import android.Manifest;
import android.annotation.SuppressLint;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.net.ConnectivityManager;
import android.net.Network;
import android.net.NetworkCapabilities;
import android.net.NetworkInfo;
import android.net.NetworkRequest;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiNetworkSuggestion;
import android.os.Build;
import android.os.Parcelable;
import android.util.Log;

import androidx.annotation.NonNull;
import androidx.annotation.RequiresApi;
import androidx.annotation.RequiresPermission;
import androidx.core.app.ActivityCompat;

import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;

public class WifiConnector {
    private static final String TAG = "WifiConnector:";

    public interface ConnectCallback {
        void onConnecting();
        void onConnected(Network network);
        void onFailed(String reason);
        void onTimeout(); // 可选：超时机制
    }

    private final Context context;
    private final WifiManager wifiManager;
    private final ConnectivityManager connectivityManager;

    private ConnectCallback callback;
    private NetworkCallbackImpl networkCallback;
    private boolean isRegistered = false;

    private final BroadcastReceiver wifiStateReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            int state = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, WifiManager.WIFI_STATE_UNKNOWN);
            if (state == WifiManager.WIFI_STATE_ENABLED) {
                Log.d(TAG, "Wi-Fi 已开启，重新尝试连接");
//                performConnect();
            }
        }
    };

    public WifiConnector(@NonNull Context context) {
        this.context = context.getApplicationContext();
        this.wifiManager = (WifiManager) this.context.getSystemService(Context.WIFI_SERVICE);
        this.connectivityManager = (ConnectivityManager) this.context.getSystemService(Context.CONNECTIVITY_SERVICE);
    }

    /**
     * 连接到指定热点
     */
    @RequiresPermission(allOf = {
            Manifest.permission.CHANGE_WIFI_STATE,
            Manifest.permission.ACCESS_FINE_LOCATION
    })
    public void connect(String ssid, String password, ConnectCallback callback) {
        this.callback = callback;

        if (!isWifiEnabled()) {
            registerWifiStateReceiver();
            if (callback != null) {
                callback.onFailed("Wi-Fi 未开启，请手动开启");
            }
            return;
        }

        performConnect(ssid, password);
    }

    private void performConnect(String ssid, String password) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            connectAndroid10AndAbove(ssid, password);
        } else {
            connectBelowAndroid10(ssid, password);
        }
    }

    // ==================== Android 10+ 使用 NetworkRequest ====================
    @RequiresApi(api = Build.VERSION_CODES.Q)
    private void connectAndroid10AndAbove(String ssid, String password) {
        if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
            if (callback != null) {
                callback.onFailed("当前系统版本不支持无密码网络连接");
            }
            return;
        }
        
        // 1. 首先尝试使用WifiNetworkSuggestion (Android 10+推荐方式)
        // 但添加更强的网络优先级设置
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            tryConnectWithNetworkSuggestion(ssid, password);
        }
        
        // 2. 同时使用WifiNetworkSpecifier来尝试直接连接
        android.net.wifi.WifiNetworkSpecifier.Builder builder = 
                new android.net.wifi.WifiNetworkSpecifier.Builder()
                        .setSsid(ssid);

        if (password != null && !password.isEmpty()) {
            builder.setWpa2Passphrase(password);
        } else {
            // 对于开放网络，确保设置正确的安全类型
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
//                builder.setSecurityType(android.net.wifi.WifiNetworkSpecifier.SECURITY_TYPE_OPEN);
            }
        }

        // 创建网络请求，增加优先级设置
        NetworkRequest.Builder requestBuilder = new NetworkRequest.Builder()
                .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
                .setNetworkSpecifier(builder.build());
        
        // 如果API级别支持，设置网络优先级为高
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
//            requestBuilder.setPriority(NetworkRequest.PRIORITY_HIGH);
        }
        
        NetworkRequest request = requestBuilder.build();

        networkCallback = new NetworkCallbackImpl(this);
        connectivityManager.requestNetwork(request, networkCallback, 15000); // 增加15秒超时

        if (callback != null) {
            callback.onConnecting();
        }
        
        // 3. 设置一个计时器，如果在指定时间内没有连接成功，尝试其他方法
        new android.os.Handler(context.getMainLooper()).postDelayed(() -> {
            // 检查是否已经连接到目标网络
            if (!isConnectedToTargetSsid(ssid)) {
                // 尝试备选方案：断开当前连接并重新请求
                attemptForceConnection(ssid, password);
            }
        }, 10000);
    }
    
    @RequiresApi(api = Build.VERSION_CODES.Q)
    private void tryConnectWithNetworkSuggestion(String ssid, String password) {
        try {
            WifiNetworkSuggestion.Builder suggestionBuilder = new WifiNetworkSuggestion.Builder()
                    .setSsid(ssid)
                    // 设置高优先级
                    .setPriority(10000);
            
            if (password != null && !password.isEmpty()) {
                suggestionBuilder.setWpa2Passphrase(password);
            } else {
                // 对于开放网络，必须设置isOpen
//                suggestionBuilder.setIsOpen(true);
            }
            
            WifiNetworkSuggestion suggestion = suggestionBuilder.build();
            List<WifiNetworkSuggestion> suggestions = new ArrayList<>();
            suggestions.add(suggestion);
            
            int status = wifiManager.addNetworkSuggestions(suggestions);
            
            if (status == WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS) {
                Log.d(TAG, "网络建议添加成功，等待系统连接");
                // 注册网络状态变化广播来监听连接结果
                registerNetworkStateReceiver();
            } else if (status == WifiManager.STATUS_NETWORK_SUGGESTIONS_ERROR_ADD_DUPLICATE) {
                Log.d(TAG, "网络建议已存在");
            } else {
                Log.e(TAG, "添加网络建议失败，状态码: " + status);
            }
        } catch (Exception e) {
            Log.e(TAG, "WifiNetworkSuggestion异常", e);
        }
    }
    
    @RequiresApi(api = Build.VERSION_CODES.Q)
    private void attemptForceConnection(String ssid, String password) {
        try {
            Log.d(TAG, "尝试强制连接到WiFi: " + ssid);
            
            // 在Android 10+上，我们不能直接断开WiFi，但可以尝试使用NetworkCallback强制应用使用特定网络
            android.net.wifi.WifiNetworkSpecifier.Builder builder = 
                    new android.net.wifi.WifiNetworkSpecifier.Builder()
                            .setSsid(ssid);

            if (password != null && !password.isEmpty()) {
                builder.setWpa2Passphrase(password);
            } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
//                builder.setSecurityType(android.net.wifi.WifiNetworkSpecifier.SECURITY_TYPE_OPEN);
            }

            NetworkRequest request = new NetworkRequest.Builder()
                    .addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
                    .setNetworkSpecifier(builder.build())
                    .build();

            // 创建一个新的NetworkCallback用于强制连接
            ConnectivityManager.NetworkCallback forceCallback = new ConnectivityManager.NetworkCallback() {
                @Override
                public void onAvailable(@NonNull Network network) {
                    super.onAvailable(network);
                    Log.d(TAG, "已获得目标网络，尝试绑定进程");
                    // 尝试将应用的流量绑定到这个网络
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                        connectivityManager.bindProcessToNetwork(network);
                    } else {
                        // 旧版本的绑定方式
                        ConnectivityManager.setProcessDefaultNetwork(network);
                    }
                    
                    if (callback != null) {
                        callback.onConnected(network);
                    }
                }
            };
            
            connectivityManager.requestNetwork(request, forceCallback, 10000);
            
            // 保存这个callback以便在stop()方法中注销
            if (networkCallback != null) {
                connectivityManager.unregisterNetworkCallback(networkCallback);
            }
            networkCallback = (NetworkCallbackImpl)forceCallback;
            
        } catch (Exception e) {
            Log.e(TAG, "强制连接异常", e);
            if (callback != null) {
                callback.onFailed("强制连接失败: " + e.getMessage());
            }
        }
    }
    
    private boolean isConnectedToTargetSsid(String targetSsid) {
        try {
            WifiInfo wifiInfo = wifiManager.getConnectionInfo();
            if (wifiInfo != null) {
                String currentSsid = wifiInfo.getSSID().replace("\"", "");
                return targetSsid.equals(currentSsid);
            }
        } catch (Exception e) {
            Log.e(TAG, "检查连接状态异常", e);
        }
        return false;
    }

    private void registerNetworkStateReceiver() {
        try {
            IntentFilter filter = new IntentFilter();
            filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
            context.registerReceiver(networkStateReceiver, filter);
            isRegistered = true;
        } catch (Exception e) {
            Log.e(TAG, "注册网络状态广播失败", e);
        }
    }
    
    private final BroadcastReceiver networkStateReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (WifiManager.NETWORK_STATE_CHANGED_ACTION.equals(action)) {
                Parcelable parcelableExtra = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
                if (parcelableExtra instanceof NetworkInfo) {
                    NetworkInfo networkInfo = (NetworkInfo) parcelableExtra;
                    if (networkInfo.isConnected()) {
                        WifiInfo wifiInfo = wifiManager.getConnectionInfo();
                        if (wifiInfo != null) {
                            String connectedSsid = wifiInfo.getSSID().replace("\"", "");
                            // 这里可以检查是否连接到了目标SSID
                            Log.d(TAG, "已连接到WiFi: " + connectedSsid);
                            if (callback != null) {
                                // 在Android 10+上，我们无法直接获取Network对象
                                callback.onConnected(null);
                            }
                            // 移除网络建议，避免积累过多
                            removeNetworkSuggestions();
                        }
                    }
                }
            }
        }
    };
    
    @RequiresApi(api = Build.VERSION_CODES.Q)
    private void removeNetworkSuggestions() {
        try {
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
                // 这里简化处理，实际应该保存添加的suggestion列表以便准确移除
                List<WifiNetworkSuggestion> suggestions = new ArrayList<>();
                wifiManager.removeNetworkSuggestions(suggestions);
            }
        } catch (Exception e) {
            Log.e(TAG, "移除网络建议失败", e);
        }
        
        // 注销广播接收器
        if (isRegistered) {
            try {
                context.unregisterReceiver(networkStateReceiver);
                isRegistered = false;
            } catch (Exception e) {
                Log.e(TAG, "注销广播接收器失败", e);
            }
        }
    }

    // ==================== Android 9 及以下 使用 WifiManager ====================
    @SuppressLint("MissingPermission")
    private void connectBelowAndroid10(String ssid, String password) {
        WifiConfiguration config = new WifiConfiguration();
        config.SSID = "\"" + ssid + "\"";

        if (password != null && !password.isEmpty()) {
            config.preSharedKey = "\"" + password + "\"";
        } else {
            config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
        }

        int netId = wifiManager.addNetwork(config);
        if (netId == -1) {
            if (callback != null) {
                callback.onFailed("添加网络失败");
            }
            return;
        }

        wifiManager.disconnect();
        boolean enabled = wifiManager.enableNetwork(netId, true);
        boolean success = wifiManager.reconnect();

        if (enabled && success) {
            // 尝试绑定网络（可能需要延迟）
            postDelayedBindNetwork(ssid);
            if (callback != null) {
                callback.onConnected(null); // Android 9 无法直接获取 Network 对象
            }
        } else {
            if (callback != null) {
                callback.onFailed("连接失败");
            }
        }
    }

    private void postDelayedBindNetwork(final String ssid) {
        new android.os.Handler(context.getMainLooper()).postDelayed(() -> {
            NetworkInfo info = connectivityManager.getActiveNetworkInfo();
            if (info != null && info.isConnected()) {
                WifiInfo wifiInfo = wifiManager.getConnectionInfo();
                if (wifiInfo != null && ssid.equals(wifiInfo.getSSID().replaceAll("\"", ""))) {
                    Log.d(TAG, "已连接到: " + ssid);
                }
            }
        }, 3000);
    }

    // ==================== NetworkCallback ====================
    private static class NetworkCallbackImpl extends ConnectivityManager.NetworkCallback {
        private final WeakReference<WifiConnector> connectorRef;

        NetworkCallbackImpl(WifiConnector connector) {
            this.connectorRef = new WeakReference<>(connector);
        }

        @Override
        public void onAvailable(Network network) {
            WifiConnector connector = connectorRef.get();
            if (connector != null && connector.callback != null) {
                connector.callback.onConnected(network);
                // 绑定网络，使应用流量走此网络
//                if (ConnectivityManager.from(connector.context).bindProcessToNetwork(network)) {
//                    Log.d(TAG, "网络已绑定");
//                }
            }
        }

        @Override
        public void onLost(Network network) {
            WifiConnector connector = connectorRef.get();
            if (connector != null && connector.callback != null) {
                connector.callback.onFailed("网络连接丢失");
            }
        }

        @Override
        public void onUnavailable() {
            WifiConnector connector = connectorRef.get();
            if (connector != null && connector.callback != null) {
                connector.callback.onFailed("无法连接到指定网络");
            }
        }
    }

    // ==================== 工具方法 ====================

    private boolean isWifiEnabled() {
        return wifiManager != null && wifiManager.isWifiEnabled();
    }

    private void registerWifiStateReceiver() {
        try {
            context.registerReceiver(wifiStateReceiver, new IntentFilter(WifiManager.WIFI_STATE_CHANGED_ACTION));
        } catch (Exception e) {
            Log.e(TAG, "注册广播失败", e);
        }
    }

    private void unregisterWifiStateReceiver() {
        try {
            context.unregisterReceiver(wifiStateReceiver);
        } catch (Exception e) {
            Log.e(TAG, "解注册广播失败", e);
        }
    }

    /**
     * 停止连接尝试
     */
    public void stop() {
        if (networkCallback != null && connectivityManager != null) {
            try {
                connectivityManager.unregisterNetworkCallback(networkCallback);
            } catch (Exception e) {
                Log.e(TAG, "unregisterNetworkCallback error", e);
            }
            // 解绑网络
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                connectivityManager.bindProcessToNetwork(null);
            } else {
                ConnectivityManager.setProcessDefaultNetwork(null);
            }
        }
        
        // 注销所有广播接收器
        unregisterWifiStateReceiver();
        if (isRegistered) {
            try {
                context.unregisterReceiver(networkStateReceiver);
                isRegistered = false;
            }
            catch (Exception e) {
                Log.e(TAG, "注销网络状态广播失败", e);
            }
        }
        
        // 移除网络建议
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            removeNetworkSuggestions();
        }
        
        callback = null;
        networkCallback = null;
    }
}
